// app/controller/plugin_data_controller.js
'use strict';

const { Controller } = require('egg');

class PluginDataController extends Controller {
  // 接收插件发送的数据
  async receiveData() {
    const { ctx } = this;
    const { batchId, timestamp, dataType, data } = ctx.request.body;
    
    try {
      // 安全检查：验证请求来源
      const userAgent = ctx.get('User-Agent');
      if (!userAgent || !userAgent.includes('Mozilla')) {
        ctx.logger.warn('[PluginData] 非法请求来源:', userAgent);
        ctx.error('禁止访问：非法请求来源', 403);
        return;
      }
      
      // 验证数据格式
      if (!data || !Array.isArray(data)) {
        ctx.error('数据格式错误: data字段必须是数组', 400);
        return;
      }
      
      // 验证批次ID格式
      if (!batchId || typeof batchId !== 'string' || batchId.length > 100) {
        ctx.error('批次ID格式错误', 400);
        return;
      }
      
      // 验证时间戳
      if (!timestamp || typeof timestamp !== 'number' || timestamp < 0) {
        ctx.error('时间戳格式错误', 400);
        return;
      }
      
      // 验证数据类型
      const validDataTypes = ['bank', 'sales_order', 'purchase_order', 'invoice', 'incoming_invoice', 'outgoing_invoice', 'announcement', 'unknown'];
      if (dataType && !validDataTypes.includes(dataType)) {
        ctx.error(`无效的数据类型: ${dataType}`, 400);
        return;
      }
      
      // 记录接收到的数据
      ctx.logger.info(`[PluginData] 接收到插件数据 - 批次ID: ${batchId}, 数据类型: ${dataType}, 条数: ${data.length}`);
      
      // 调用服务处理数据
      const result = await ctx.service.pluginDataService.processPluginData({
        batchId,
        timestamp,
        dataType,
        data
      });
      
      ctx.success({
        receivedCount: data.length,
        processedCount: result.processedCount,
        batchId: batchId
      }, 'success');
    } catch (error) {
      ctx.logger.error('[PluginData] 处理插件数据失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 查询数据处理状态
  async queryDataStatus() {
    const { ctx } = this;
    const { batchId } = ctx.query;
    
    if (!batchId) {
      ctx.error('缺少批次ID参数', 400);
      return;
    }
    
    // 验证批次ID格式
    if (typeof batchId !== 'string' || batchId.length > 100) {
      ctx.error('批次ID格式错误', 400);
      return;
    }
    
    try {
      const status = await ctx.service.pluginDataService.getDataProcessingStatus(batchId);
      
      ctx.success(status, 'success');
    } catch (error) {
      ctx.logger.error('[PluginData] 查询数据处理状态失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 获取数据处理统计信息
  async getDataStatistics() {
    const { ctx } = this;
    
    try {
      const statistics = await ctx.service.pluginDataService.getDataStatistics();
      
      ctx.success(statistics, 'success');
    } catch (error) {
      ctx.logger.error('[PluginData] 获取数据统计信息失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 查询批次列表
  async queryBatches() {
    const { ctx } = this;
    const { status, page = 1, pageSize = 20 } = ctx.query;
    
    // 参数验证
    const pageNum = parseInt(page);
    const size = parseInt(pageSize);
    
    if (isNaN(pageNum) || pageNum < 1) {
      ctx.error('页码必须是正整数', 400);
      return;
    }
    
    if (isNaN(size) || size < 1 || size > 100) {
      ctx.error('页面大小必须是1-100之间的正整数', 400);
      return;
    }
    
    // 状态验证
    if (status && !['pending', 'processing', 'completed', 'failed'].includes(status)) {
      ctx.error('状态值无效', 400);
      return;
    }
    
    try {
      // 构建查询条件
      const where = {};
      if (status) {
        where.status = status;
      }
      
      // 查询批次列表
      const batches = await ctx.model.PluginDataBatchModel.findAndCountAll({
        where,
        order: [['createdAt', 'DESC']],
        limit: size,
        offset: (pageNum - 1) * size
      });
      
      ctx.page(batches.rows, batches.count, pageNum, size);
    } catch (error) {
      ctx.logger.error('[PluginData] 查询批次列表失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 查询数据项列表
  async queryDataItems() {
    const { ctx } = this;
    const { batchId, category, status, page = 1, pageSize = 20 } = ctx.query;
    
    // 参数验证
    const pageNum = parseInt(page);
    const size = parseInt(pageSize);
    
    if (isNaN(pageNum) || pageNum < 1) {
      ctx.error('页码必须是正整数', 400);
      return;
    }
    
    if (isNaN(size) || size < 1 || size > 100) {
      ctx.error('页面大小必须是1-100之间的正整数', 400);
      return;
    }
    
    // 参数验证
    if (batchId && (typeof batchId !== 'string' || batchId.length > 100)) {
      ctx.error('批次ID格式错误', 400);
      return;
    }
    
    // 分类验证
    if (category && !['bank', 'sales_order', 'purchase_order', 'invoice', 'incoming_invoice', 'outgoing_invoice', 'announcement', 'unknown'].includes(category)) {
      ctx.error('数据分类无效', 400);
      return;
    }
    
    // 状态验证
    if (status && !['pending', 'processed', 'failed'].includes(status)) {
      ctx.error('状态值无效', 400);
      return;
    }
    
    try {
      // 构建查询条件
      const where = {};
      if (batchId) {
        where.batchId = batchId;
      }
      if (category) {
        where.category = category;
      }
      if (status) {
        where.status = status;
      }
      
      // 查询数据项列表，使用ID排序避免大数据量排序问题
      const items = await ctx.model.PluginDataItemModel.findAndCountAll({
        where,
        order: [['id', 'DESC']], // 使用主键ID排序，避免createdAt排序的性能问题
        limit: size,
        offset: (pageNum - 1) * size
      });
      
      ctx.page(items.rows, items.count, pageNum, size);
    } catch (error) {
      ctx.logger.error('[PluginData] 查询数据项列表失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 获取数据项详情
  async getDataItemDetail() {
    const { ctx } = this;
    const { itemId } = ctx.params;
    
    // 验证参数
    if (!itemId || typeof itemId !== 'string' || itemId.length > 100) {
      ctx.error('数据项ID格式错误', 400);
      return;
    }
    
    try {
      // 查询数据项详情
      const item = await ctx.model.PluginDataItemModel.findOne({
        where: { itemId: itemId }
      });
      
      if (!item) {
        ctx.error('数据项不存在', 404);
        return;
      }
      
      ctx.success(item, 'success');
    } catch (error) {
      ctx.logger.error('[PluginData] 获取数据项详情失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 重新处理数据项
  async reprocessDataItem() {
    const { ctx } = this;
    const { itemId } = ctx.params;
    
    // 验证参数
    if (!itemId || typeof itemId !== 'string' || itemId.length > 100) {
      ctx.error('数据项ID格式错误', 400);
      return;
    }
    
    try {
      // 查询数据项
      const item = await ctx.model.PluginDataItemModel.findOne({
        where: { itemId: itemId }
      });
      
      if (!item) {
        ctx.error('数据项不存在', 404);
        return;
      }
      
      // 调用服务重新处理数据
      const result = await ctx.service.pluginDataService.reprocessDataItem(item);
      
      ctx.success(result, 'success');
    } catch (error) {
      ctx.logger.error('[PluginData] 重新处理数据项失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
  
  // 删除数据项
  async deleteDataItem() {
    const { ctx } = this;
    const { itemId } = ctx.params;
    
    // 验证参数
    if (!itemId || typeof itemId !== 'string' || itemId.length > 100) {
      ctx.error('数据项ID格式错误', 400);
      return;
    }
    
    try {
      // 删除数据项
      const result = await ctx.model.PluginDataItemModel.destroy({
        where: { itemId: itemId }
      });
      
      if (result === 0) {
        ctx.error('数据项不存在', 404);
        return;
      }
      
      ctx.success(null, '数据项删除成功');
    } catch (error) {
      ctx.logger.error('[PluginData] 删除数据项失败:', error);
      ctx.error('服务器内部错误: ' + error.message, 500, {
        error: error.message
      });
    }
  }
}

module.exports = PluginDataController;